package com.piesat.test;

import com.baomidou.mybatisplus.annotation.TableField;
import com.piesat.quake.business.device.model.EventData;
import com.zaxxer.hikari.HikariDataSource;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CreateTableFromModel {
    /**
     * CREATE TABLE `system_user` (
     *   `user_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
     *   `user_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录名',
     *   `password` char(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录密码',
     *   `project_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '单位名称',
     *   `id_number` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '身份证号',
     *   `real_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '真实姓名',
     *   `sex` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别',
     *   `cellphone` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '移动电话',
     *   `user_type` tinyint(1) DEFAULT '0' COMMENT '用户类型',
     *   `state` tinyint(1) NOT NULL DEFAULT '1' COMMENT '用户状态（默认值0）：\r\n1 - 正常\r\n0 - 已冻结',
     *   `application_code` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '公众号申请码',
     *   `create_time` datetime NOT NULL COMMENT '创建时间',
     *   `update_time` datetime DEFAULT NULL COMMENT '修改时间',
     *   PRIMARY KEY (`user_id`) USING BTREE,
     *   UNIQUE KEY `user_name` (`user_name`) USING BTREE,
     *   UNIQUE KEY `cellphone` (`cellphone`) USING BTREE
     * ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表'
     */
    @Test
    public void create(){
        HikariDataSource hikariDataSource = new HikariDataSource();
        hikariDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        hikariDataSource.setJdbcUrl("jdbc:mysql://39.97.237.76:3306/quake?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&useSSL=false");
        hikariDataSource.setUsername("root");
        hikariDataSource.setPassword("asd123456");
        try {
            Connection connection = hikariDataSource.getConnection();
            Statement statement = connection.createStatement();
            createTable(statement, EventData.class,"event_data");
//            Set<Class<?>> classes= ClassUtils.getAnnotationClasses("com.piesat.business", TableName.class);
//            for (Class<?> aClass : classes) {
//                TableName annotation = aClass.getAnnotation(TableName.class);
//                String value = annotation.value();
//                createTable(statement, aClass,value);
//            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    private void createTable(Statement statement, Class<?> aClass, String tableName) throws SQLException {
        StringBuilder sb=new StringBuilder("CREATE TABLE ");
        sb.append(tableName).append(" (\r\n");
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            boolean isStatic = Modifier.isStatic(field.getModifiers());
            if (!isStatic){
                TableField annotation = field.getAnnotation(TableField.class);
                if (annotation==null){
                    sb.append("`").append(xX2x_x(field.getName())).append("`").append(" ");
                    Class<?> type = field.getType();
                    if (type==String.class){
                        sb.append("varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,");
                    }else if (type==Integer.class){
                        sb.append("int(4) NOT NULL,");
                    }else if (type== Date.class){
                        sb.append("datetime NOT NULL,");
                    }else if (type== Long.class){
                        sb.append("bigint(8) NOT NULL,");
                    }else if (type== Double.class){
                        sb.append("double NOT NULL,");
                    }else if (type== Float.class){
                        sb.append("float NOT NULL,");
                    }else if (type== Byte.class){
                        sb.append("tinyint NOT NULL,");
                    }
                    sb.append("\r\n");
                }
            }
        }
        sb.deleteCharAt(sb.length()-3);
        sb.append(")ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci");
        String sql = sb.toString();
        System.out.println(sql);
        statement.execute(sql);
    }

    /**
     * @author Howe
     * @Description 将驼峰转为下划线
     * @param str
     * @return java.lang.String
     * @Date   2022/4/22 13:11
     * @since  1.0.0
     */
    public static String xX2x_x(String str) {
        Pattern compile = Pattern.compile("[A-Z]");
        Matcher matcher = compile.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            matcher.appendReplacement(sb,  "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * @author Howe
     * @Description 将下划线转为驼峰
     * @param str
     * @return java.lang.String
     * @Date   2022/4/22 13:12
     * @since  1.0.0
     */
    public static String x_x2xX(String str) {
        str = str.toLowerCase();
        Pattern compile = Pattern.compile("_[a-z]");
        Matcher matcher = compile.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            matcher.appendReplacement(sb,  matcher.group(0).toUpperCase().replace("_",""));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }
}
